// 组合两个函数且传入的函数只接受一个参数
const compose = (a,b) => c => a(b(c))
const fn1 = x => x * 2
const fn2 = y => y + 3
let tryfn = compose(fn2,fn1)
const ass = tryfn(1)
ass

const partial = (fn, ...args)=>{
  let _args = args
  return function(...fullArgs){
    let arg = 0
    for(let i = 0; i< _args.length && arg < fullArgs.length;i++){
      if(_args[i] === undefined){
        _args[i] = fullArgs[arg++]
      }
      return fn.apply(null,_args)
    }
  }
}
const map = (array,fn) => {
  let results = []
  for(let val of array){
    results.push(fn(val))
  }
  return results
}
const filter = (array,fn) => {
  let results = []
  for (let val of array){
    fn(val) ? results.push(val) : ''
  }
  return results
}
const reduce = (array, fn, initVal) => {
  let result
  result = initVal !== undefined ? initVal : array[0]

  if(initVal === undefined){
    for(let i =0; i< array.length;i++){
      result = fn(result,array[i])
    }
  } else {
    for( let val of array){
      result = fn(result, val)
    }
  }
  return [result]
}
let apressBooks = [
  {
    id:1,
    title: 'html',
    author: 'derek',
    rating: [4.1],
    data:[{good: 4,error: 1}]
  },{
    id:1,
    title: 'css',
    author: 'derek',
    rating: [5.1],
    data:[{good: 4,error: 1}]
  },{
    id:1,
    title: 'javascript',
    author: 'tom',
    rating: [6.1],
    data:[{good: 4,error: 1}]
  },{
    id:1,
    title: 'node.js',
    author: 'derek',
    rating: [7.1],
    data:[{good: 4,error: 1}]
  }
]
let filterItem = item => item.rating[0] > 7
let projectInfo = item => {
  return {
    title: item.title,
    author:item.author
  }
}
// 组合两个多参数的函数
let filterGoodItem = partial(filter,undefined,filterItem)
let mapProjectData = partial(map, undefined, projectInfo)
let getData = compose(mapProjectData,filterGoodItem)
let result = getData(apressBooks)
result

// 组合多个函数
const moreCompose = (...fns) => value => reduce(fns.reverse(), (acc, fn) => fn(acc),value)
const splitStr = str => str.split(' ')
const getLen = arr => arr.length
const getStrLen = moreCompose(getLen, splitStr)
let num = getStrLen('afg af fg afg d wer sf g')
const oddOrEven = num => num % 2 ? 'odd' : 'even'
num

const getOddOrEven = moreCompose(oddOrEven,getLen,splitStr)
const type = getOddOrEven('afg dfg af f af wersa fg s d g')
type
